import { AudioClip, AudioSource } from "cc";
import { IAudioEngine } from "../cfw/audio/IAudioEngine";

export class AudioEngine implements IAudioEngine {
    protected musicMgr: AudioSource = new AudioSource()

    protected audioBuffer: AudioSource[] = []

    protected effectMap: { [k: number]: AudioSource } = {}
    protected effectID: number = 0;
    protected musicAudioID: number = 0;

    protected timeBuffer: { [k: number]: number } = {}
    constructor() {
        this.musicAudioID = this.createEffectID();
    }
    getMaxAudioInstance() {
        return AudioSource.maxAudioChannel;
    }

    playMusic(res: AudioClip, isLoop: boolean) {
        this.musicMgr.stop();
        this.musicMgr.clip = res;
        this.musicMgr.loop = isLoop;

        this.musicMgr.pause();

        this.musicMgr.play();
        this.effectMap[this.musicAudioID] = this.musicMgr;
        return this.musicAudioID;
    }


    setFinishCallback(audioId: number, func: Function) {
        let time = this.timeBuffer[audioId]
        if (time) {
            // engine.log(' setFinishCallback audioId', audioId, 'time', time)
            setTimeout(() => {
                func();
            }, time * 1000);
        }

        // let as: AudioSource = this.effectMap[audioId]
        // if (as) {

        // } else {
        //     func();
        // }
    }

    protected createEffectID() {
        return Date.now() + this.effectID++
    }

    pauseMusic() {
        this.musicMgr.pause()
    }

    resumeMusic() {
        this.musicMgr.play()
    }

    stopMusic() {
        this.musicMgr.stop();
    }

    setMusicVolume(count: number) {
        this.musicMgr.volume = count
    }

    isMusicPlaying() {
        return this.musicMgr.playing
    }

    protected getAudioSource(res: AudioClip, isLoop: boolean) {
        let as: AudioSource = this.audioBuffer.length > 0 ? this.audioBuffer.shift() : new AudioSource()
        as.clip = res;
        as.loop = isLoop;
        return as;
    }

    playEffect(res: AudioClip, playCount: number, func?: Function): number {
        let isLoop = playCount == 0 ? true : false
        let audioID = this.createEffectID();
        this.timeBuffer[audioID] = res.getDuration()
        if (this.timeBuffer[audioID] <= 2) {
            this.musicMgr.playOneShot(res)
        } else {
            let as: AudioSource = this.getAudioSource(res, isLoop)
            this.effectMap[audioID] = as;
            as.play();
        }
        if (func) {
            this.setFinishCallback(audioID, func)
        }
        return audioID
    }

    pauseEffect(audioId: number) {
        // audioEngine.pauseEffect(audioId);
        let as: AudioSource = this.effectMap[audioId]
        if (as) {
            as.pause();
        }
    }



    resumeEffect(audioId: number) {
        // audioEngine.resumeEffect(audioId);
        let as: AudioSource = this.effectMap[audioId]
        if (as) {
            as.play();
        }
    }

    setEffectsVolume(count: number) {
        // audioEngine.setEffectsVolume(count);
        this.musicMgr.volume = count;
    }

    stopEffect(audioId: number) {
        // audioEngine.stopEffect(audioId);
        let as: AudioSource = this.effectMap[audioId]
        if (as) {
            as.stop();
            delete this.effectMap[audioId]
            delete this.timeBuffer[audioId]
            this.audioBuffer.push(as)
        }
    }


    uncacheAll() {
        // audioEngine.uncacheAll()
    }
}
